<template>
  <div class="kb-page">
    <button v-if="!isMobile && !showSidebar" class="kb-sidebar-toggle" @click="showSidebar = true" title="显示侧边栏">
      <i class="fa-solid fa-chevron-right"></i>
    </button>
    <button v-if="isMobile" class="kb-mobile-toggle" @click="showSidebar = true">☰ 菜单</button>

    <div v-if="isMobile && showSidebar" class="kb-sidebar-mask" @click="showSidebar = false" />

    <aside
      v-if="(!isMobile && showSidebar) || (isMobile && showSidebar)"
      class="kb-sidebar"
      :class="{ 'kb-sidebar-fixed': isMobile }"
    >
      <div class="kb-sidebar-head">
        <h2>知识库</h2>
        <div class="kb-sidebar-actions">
          <button v-if="!isMobile" class="kb-sidebar-toggle-btn" @click="showSidebar = false" title="隐藏侧边栏">
            <i class="fa-solid fa-chevron-left"></i>
          </button>
          <button v-if="isMobile" class="kb-close" @click="showSidebar = false">×</button>
        </div>
      </div>

      <button class="kb-primary" @click="handleNewNote(null)">
        + 新增笔记
      </button>

      <input
        v-model="searchTerm"
        type="text"
        placeholder="搜索笔记"
        class="kb-search"
      />

      <div class="kb-tree-wrapper">
        <NoteTree
          :notes="notes"
          :selected-note="selectedNote"
          :on-note-click="handleNoteClick"
          :on-new-note="handleNewNote"
          :on-edit-note="handleEditNote"
          :on-delete-note="handleDeleteNote"
          :on-rename-note="handleRenameNote"
          :search-term="searchTerm"
          :expanded-nodes="expandedNodes"
          :toggle-expand="toggleExpand"
        />
      </div>
    </aside>

    <main class="kb-main">
      <div class="kb-main-card">
        <EditorNote
          v-if="isCreating"
          :selected-note="selectedNote"
          :note-content="noteContent"
          :set-note-content="(val) => (noteContent = val)"
          :note-title="noteTitle"
          :set-note-title="(val) => (noteTitle = val)"
          :handle-save="handleSave"
          :is-mobile="isMobile"
          :on-toggle-sidebar="() => (showSidebar = true)"
        />
        <NotesList
          v-else
          :selected-note="selectedNote"
          :root-notes="rootNotes"
          :is-mobile="isMobile"
          :on-toggle-sidebar="() => (showSidebar = true)"
          :on-note-click="handleNoteClick"
          :on-edit-note="handleEditNote"
          :on-back-to-list="handleBackToList"
          :on-note-updated="handleNoteUpdated"
        />
      </div>
    </main>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import NoteTree from './NoteTree.vue';
import NotesList from './NotesList.vue';
import EditorNote from './EditorNote.vue';

const notes = ref([]);
const selectedNote = ref(null);
const noteContent = ref('');
const noteTitle = ref('');
const searchTerm = ref('');
const expandedNodes = ref({});
const isCreating = ref(false);
const isMobile = ref(false);
const showSidebar = ref(true);
const router = useRouter();

onMounted(() => {
  const updateIsMobile = () => {
    isMobile.value = window.innerWidth < 768;
  };

  updateIsMobile();
  window.addEventListener('resize', updateIsMobile);

  checkLogin();
  fetchNotes();
});

async function checkLogin() {
  const res = await fetch('/api/notes/getNotes');
  if (res.status === 401) {
    router.push('/login');
  }
}

async function fetchNotes() {
  try {
    const res = await fetch('/api/notes/getNotes');
    const data = await res.json();

    const buildTree = (allNotes, parentId = null, depth = 0) => {
      return allNotes
        .filter((n) => n.parent_id === parentId)
        .map((n) => ({
          ...n,
          depth,
          children: buildTree(allNotes, n.id, depth + 1),
        }));
    };

    const treeData = buildTree(data);
    notes.value = treeData;

    const expanded = {};
    const expandAll = (nodes) => {
      nodes.forEach((node) => {
        if (node.children && node.children.length) {
          expanded[node.id] = true;
          expandAll(node.children);
        }
      });
    };
    expandAll(treeData);
    expandedNodes.value = expanded;
  } catch (err) {
    console.error(err);
  }
}

async function handleNoteClick(note) {
  isCreating.value = false;
  selectedNote.value = note;
  if (isMobile.value) showSidebar.value = false;
  try {
    const res = await fetch(`/api/notes/getNoteContent?noteId=${note.id}`);
    const data = await res.json();
    noteContent.value = data.content || '';
    noteTitle.value = note.name || '';
  } catch (err) {
    console.error(err);
    noteContent.value = '';
  }
}

function handleNewNote(parentId = null) {
  isCreating.value = true;
  selectedNote.value = { id: null, parentId };
  noteTitle.value = '笔记标题';
  noteContent.value = '';
}

function handleEditNote(note) {
  isCreating.value = true;
  selectedNote.value = { id: note.id };
  noteTitle.value = note.name;
  noteContent.value = note.content;
}

async function handleSave() {
  if (selectedNote.value.id == null) {
    try {
      const res = await fetch('/api/notes/createNote', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          parentId: selectedNote.value.parentId,
          name: noteTitle.value,
          content: noteContent.value,
        }),
      });
      const newNote = await res.json();
      await fetchNotes();
      selectedNote.value = newNote;
      isCreating.value = false;
    } catch (err) {
      console.error(err);
    }
  } else {
    try {
      await fetch('/api/notes/saveNote', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          noteId: selectedNote.value.id,
          name: noteTitle.value,
          content: noteContent.value,
          icon: selectedNote.value?.icon || null,
          iconColor: selectedNote.value?.iconColor || null,
          changeSummary: null, // 可以扩展为让用户输入修改说明
        }),
      });
      await fetchNotes();
    } catch (err) {
      console.error(err);
    }
  }
}

async function handleDeleteNote(noteId) {
  try {
    await fetch('/api/notes/deleteNote', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ noteId }),
    });
    await fetchNotes();
    if (selectedNote.value && selectedNote.value.id === noteId) {
      selectedNote.value = null;
      noteContent.value = '';
      noteTitle.value = '';
    }
  } catch (err) {
    console.error(err);
  }
}

async function handleRenameNote(noteId, newName) {
  try {
    await fetch('/api/notes/renameNote', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ noteId, newName }),
    });
    await fetchNotes();
  } catch (err) {
    console.error(err);
  }
}

function toggleExpand(id) {
  expandedNodes.value = { ...expandedNodes.value, [id]: !expandedNodes.value[id] };
}

function handleBackToList() {
  selectedNote.value = null;
  noteContent.value = '';
  noteTitle.value = '';
}

// 处理笔记更新（版本恢复后）
async function handleNoteUpdated() {
  if (selectedNote.value) {
    // 重新加载笔记内容
    await fetchNoteContent(selectedNote.value.id);
    // 重新加载笔记列表以更新时间戳
    await fetchNotes();
  }
}

const rootNotes = computed(() => {
  if (!Array.isArray(notes.value)) return [];
  return notes.value
    .filter((n) => !n.parentId)
    .sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at));
});
</script>

<style scoped>
:global(body) {
  background: #edf1f8;
}

.kb-page {
  position: relative;
  min-height: calc(100vh - 72px);
  display: flex;
  background: linear-gradient(180deg, #eff3fa 0%, #e6ebf6 100%);
  overflow: hidden;
}

.kb-sidebar-toggle {
  position: absolute;
  top: 10%;
  left: 0;
  transform: translateY(-50%);
  z-index: 20;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 0 8px 8px 0;
  background: rgba(5, 64, 128, 0.9);
  box-shadow: 2px 0 8px rgba(15, 23, 42, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #ffa700;
}

.kb-sidebar-toggle:hover {
  background: rgba(76, 110, 245, 0.1);
  color: #4c6ef5;
}

.kb-sidebar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.kb-sidebar-toggle-btn {
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 6px;
  background: rgba(5, 64, 128, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: #ffa700;;
  transition: color 0.2s ease;
  border-radius: 8px;
  border: 1px solid rgba(207, 215, 235, 0.8);
}

.kb-sidebar-toggle-btn:hover {
  color: #4c6ef5;
}

.kb-mobile-toggle {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 20;
  border: none;
  border-radius: 999px;
  padding: 10px 16px;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 8px 20px rgba(15, 23, 42, 0.15);
  font-size: 14px;
  color: #4b5675;
}

.kb-sidebar-mask {
  position: fixed;
  inset: 0;
  z-index: 25;
  background: rgba(15, 23, 42, 0.35);
}

.kb-sidebar {
  width: 320px;
  padding: 28px 24px;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(8px);
  border-right: 1px solid rgba(146, 157, 190, 0.2);
  box-shadow: 12px 0 35px rgba(12, 18, 38, 0.08);
  z-index: 30;
  display: flex;
  flex-direction: column;
}

.kb-sidebar-fixed {
  position: fixed;
  inset: 0;
  max-width: 300px;
}

.kb-sidebar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
  height: 20px;
}

.kb-sidebar-head h2 {
  font-size: 20px;
  font-weight: 700;
  color: #2d3551;
}

.kb-close {
  border: none;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  color: #97a1bb;
  cursor: pointer;
}

.kb-primary {
  border: none;
  border-radius: 14px;
  padding: 12px 16px;
  background: linear-gradient(120deg, #4c6ef5, #5f8bff);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 12px 25px rgba(76, 110, 245, 0.25);
  margin-bottom: 10px;
}

.kb-search {
  width: 100%;
  border: 1px solid rgba(151, 161, 187, 0.4);
  border-radius: 12px;
  padding: 10px 0px;
  font-size: 14px;
  margin-bottom: 10px;
  background: rgba(255, 255, 255, 0.85);
}

.kb-tree-wrapper {
  flex: 1;
  overflow-y: auto;
  padding-right: 6px;
}

.kb-main {
  flex: 1;
  display: flex;
  align-items: stretch;
  justify-content: center;
  transition: margin-left 0.3s ease;
}

.kb-main-card {
  width: 100%;
  max-width: 1200px;
  background: rgba(255, 255, 255, 0.95);
  box-shadow: 0 20px 45px rgba(15, 23, 42, 0.12);
}

@media (max-width: 1024px) {
  .kb-sidebar {
    width: 280px;
  }

  .kb-main {
    padding: 24px;
  }
}

@media (max-width: 768px) {
  .kb-page {
    flex-direction: column;
  }

  .kb-main {
    padding: 16px;
  }

  .kb-main-card {
    border-radius: 18px;
  }
}
</style>
